(use '[commonfact :only (factorial_range)])


(defn factorial_pair [pair]
  (factorial_range (first pair) (last pair)))


(defn start_factorial_agent [ag]
  (send ag factorial_pair))


(let [worker_count (Integer/parseInt (str (nth *command-line-args* 0)))
      top (Integer/parseInt (str (nth *command-line-args* 1)))
      step (/ top worker_count)
      agents (map (fn [top] (agent [(inc (- top step)) top]))
                  (range top 1 (- step)))]
  (do
    (apply await (map start_factorial_agent agents))  ; map is lazy
    (println (reduce (fn [x ag] (* x @ag)) 1 agents))
    (shutdown-agents)
  )
)
